package com.weng.cloud.commons.base;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;

import javax.annotation.PreDestroy;
import java.io.IOException;
import java.nio.charset.Charset;

/**
 * @Author: weng
 * @Date: 2022/2/18
 * @Description: com.weng.cloud.commons
 */

public class HttpUtil {

    private final static CloseableHttpClient CLIENT_DEFAULT;
    //private final static RequestConfig CONFIG_DEFAULT;

    private final static Header[] HEADERS_DEFAULT;
    private final static Charset CHARSET_DEFAULT;

    static{
        CLIENT_DEFAULT = HttpClients.createDefault();
        HEADERS_DEFAULT = new BasicHeader[]{
                new BasicHeader("Content-Type","application/json;charset=utf-8")
        };
        CHARSET_DEFAULT = Charset.forName("utf-8");
    }

    @PreDestroy
    private static void preDestroy(){
        if(CLIENT_DEFAULT != null){
            try {
                CLIENT_DEFAULT.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static CloseableHttpClient client(CloseableHttpClient httpClient){
        return ObjectUtils.firstNonNull(httpClient, CLIENT_DEFAULT);
    }

    private static Header[] headers(Header ...headers){
        return ObjectUtils.firstNonNull(headers,HEADERS_DEFAULT);
    }

    private static Charset charset(Charset charset){
        return ObjectUtils.firstNonNull(charset,CHARSET_DEFAULT);
    }

    private static String url(String protocol ,String ip ,String port ,String api){
        if(StringUtils.isAnyBlank(protocol ,ip ,port ,api)){
            return null;
        }
        return protocol + "://" + ip + ":" + port + "/" + api;
    }

    private static HttpPost httpPost(String url, Object param, Header[] headers,Charset charset) {
        HttpPost result;
        if(StringUtils.isBlank(url)){
            return null;
        }
        String json = JsonUtil.toText(param);
        if(StringUtils.isBlank(json)){
            return null;
        }
        result = new HttpPost(url);
        result.setHeaders(headers(headers));
        result.setEntity(new StringEntity(json,charset(charset)));
        return result;
    }

    private static HttpPost httpPost(String url, Object param) {
        return httpPost(url,param,null,null);
    }

    private static String toResponseBodyString(CloseableHttpResponse httpResponse,Charset charset) throws IOException {
        return EntityUtils.toString(httpResponse.getEntity(),charset(charset));
    }

    private static String toResponseBodyString(CloseableHttpResponse httpResponse) throws IOException {
        return toResponseBodyString(httpResponse,null);
    }

    public static String post(String url, Object param, CloseableHttpClient client) throws IOException {
        String result = null;
        HttpPost httpPost = httpPost(url, param);
        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = client(client).execute(httpPost);
            result = toResponseBodyString(httpResponse);
        } catch (IOException e) {
            throw e;
        } finally {
            if(httpResponse != null){
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    throw e;
                }
            }
        }
        return result;
    }

    public static String post(String protocol ,String ip ,String port ,String api, Object param) throws IOException {
        return post(url(protocol,ip,port,api),param,null);
    }
}
